//
//  Buttons.swift
//  SwiftUiBaseStudy
//
//  Created by Daniel on 2023/11/18.
//

import SwiftUI

//haptic 函数用于触发通知类的触觉反馈
func haptic(type:UINotificationFeedbackGenerator.FeedbackType){
    UINotificationFeedbackGenerator().notificationOccurred(type)
}
//impact 函数用于触发冲击类的触觉反馈
func impact(type:UIImpactFeedbackGenerator.FeedbackStyle){
    UIImpactFeedbackGenerator(style: type).impactOccurred()
}

struct Buttons: View {
    // 背景颜色
    var backgroundColor = Color(#colorLiteral(red: 0.8980392157, green: 0.9333333333, blue: 1, alpha: 1))
    
    
    
    var body: some View {
        VStack(spacing: 50.0) {
            RectangleButton()
            
            circleButton()
            
            payButton()
            
        }
        .frame(maxWidth: .infinity,maxHeight: .infinity)
        .background(backgroundColor)
        .ignoresSafeArea(.all)
        
        
    }
}

#Preview {
    Buttons()
}

struct RectangleButton: View {
    
    // 外部阴影
    var shadowColor = Color(#colorLiteral(red: 0.7608050108, green: 0.8164883852, blue: 0.9259157777, alpha: 1))
    var whiteColor = Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1))
    
    // 内部阴影
    var btnBgColor = Color(#colorLiteral(red: 0.7608050108, green: 0.8164883852, blue: 0.9259157777, alpha: 1))
    var linearColors = [Color(#colorLiteral(red: 0.9019607843, green: 0.9294117647, blue: 0.9882352941, alpha: 1)), Color.white]
    
    // 阴影颜色
    var outShadowColor =  Color(#colorLiteral(red: 0.7294117647, green: 0.7843137255, blue: 0.8941176471, alpha: 1))
    
    // 图标背景颜色
    var iconBgColor = Color(#colorLiteral(red: 0.4196078431, green: 0.2980392157, blue: 0.9490196078, alpha: 1))
    var iconShadowColor = Color(#colorLiteral(red: 0.4196078431, green: 0.2980392157, blue: 0.9490196078, alpha: 1))
    
    // 点击 缩放效果
    @State var tap = false
    
    // 长按效果
    @State var press = false
    
    
    var body: some View {
        Text("Swift UI")
            .font(.system(size: 20,weight: .semibold,design: .rounded))
            .frame(width: 200,height: 60)
            .background(
                ZStack{
                    press ? btnBgColor:whiteColor
                    RoundedRectangle(cornerRadius: 16)
                        .foregroundStyle(press ? shadowColor:whiteColor)
                        .blur(radius: 4)
                        .offset(x:-4,y:-4)
                    RoundedRectangle(cornerRadius: 16)
                        .fill(
                            LinearGradient(colors: linearColors, startPoint: .topLeading, endPoint: .bottomTrailing)
                        )
                        .padding(2)
                        .blur(radius: 2)
                }
            )
            .clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
            .overlay{
                HStack {
                    Image(systemName: "person.crop.circle")
                        .font(.system(size: 24,weight: .light))
                        .foregroundStyle(whiteColor.opacity(press ? 0:1))
                        .frame(width:press ? 70: 54,height:press ? 4:50)
                        .background(iconBgColor)
                        .clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
                        .offset(x:press ? 65:-10,y:press ? 16:0)
                    Spacer()
                }
                
            }
            .shadow(color:press ? whiteColor:shadowColor,radius: 20,x:20,y:20)
            .shadow(color:press ? shadowColor:whiteColor,radius: 20,x:-20,y:-20)
            .scaleEffect(tap ? 1.2:1)
            .animation(.spring(response:0.5,dampingFraction: 0.5), value: tap || press)
            .gesture(
                LongPressGesture(minimumDuration: 0.5,maximumDistance: 10)
                    .onChanged{value in
                        tap = true
                        impact(type: .heavy)
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1){
                            tap = false
                        }
                    }
                    .onEnded{ value in
                        haptic(type: .success)
                        press.toggle()
                    }
            )
    }
}

struct circleButton: View {
    
    // 外部阴影
    var shadowColor = Color(#colorLiteral(red: 0.7608050108, green: 0.8164883852, blue: 0.9259157777, alpha: 1))
    var whiteColor = Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1))
    
    var innerColor = Color(#colorLiteral(red: 0.9019607843, green: 0.9294117647, blue: 0.9882352941, alpha: 1))
    
    // 点击 缩放效果
    @State var tap = false
    
    // 长按效果
    @State var press = false
    var body: some View {
        ZStack {
            Image(systemName: "sun.max")
                .font(.system(size: 44,weight: .light))
                .offset(x: press ? -90:0,y:press ? -90:0)
                .rotation3DEffect(
                    Angle(degrees: press ? 20:0),
                    axis: (x: 10, y: -10, z: 0.0)
                )
            Image(systemName: "moon")
                .font(.system(size: 44,weight: .light))
                .offset(x: press ? 0:90,y:press ? 0:90)
                .rotation3DEffect(
                    Angle(degrees: press ? 0:20),
                    axis: (x: -10, y: 10, z: 0.0)
                )
        }
        .frame(width: 100,height: 100)
        .background(
            ZStack{
                LinearGradient(gradient: Gradient(colors: [press ? innerColor:whiteColor, press ? whiteColor: innerColor]), startPoint: .topLeading, endPoint: .bottomTrailing)
                Circle()
                    .stroke(Color.clear,lineWidth:10)
                    .shadow(color:shadowColor,radius: press ? 20: 5,x: press ? -5: 5,y:press ? -5: 5)
                Circle()
                    .stroke(Color.clear,lineWidth:10)
                    .shadow(color:whiteColor,radius: 3,x:press ? 3:-3,y:press ? 3:-3)
            }
        )
        .clipShape(Circle())
        .shadow(color:press ? whiteColor:shadowColor,radius: 20,x:20,y:20)
        .shadow(color:press ?shadowColor:whiteColor,radius: 20,x:-20,y:-20)
        .scaleEffect(tap ? 1.2:1)
        .animation(.spring(response:0.5,dampingFraction: 0.5), value: tap || press)
        .gesture(
            LongPressGesture(minimumDuration: 0.5,maximumDistance: 10)
                .onChanged{value in
                    impact(type: .heavy)
                    tap = true
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1){
                        tap = false
                    }
                }
                .onEnded{ value in
                    haptic(type: .success)
                    press.toggle()
                }
        )
    }
}

struct payButton: View {
    
    // 外部阴影
    var shadowColor = Color(#colorLiteral(red: 0.7608050108, green: 0.8164883852, blue: 0.9259157777, alpha: 1))
    var whiteColor = Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1))
    
    var innerColor = Color(#colorLiteral(red: 0.9019607843, green: 0.9294117647, blue: 0.9882352941, alpha: 1))
    
    var background = Color(#colorLiteral(red: 0.3647058904, green: 0.06666667014,     blue: 0.9686274529, alpha: 1))
    
    // 环形颜色
    var circleColor1 = #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1)
    var circleColor2 = #colorLiteral(red: 0.4196078431, green: 0.2980392157, blue: 0.9490196078, alpha: 1)
    var circleColor3 = #colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1)
    
    // 点击 缩放效果
    @GestureState var tap = false
    
    // 长按效果
    @State var press = false
    var body: some View {
        ZStack {
            Image("fingerprint")
                .scaleEffect(press ? 0:1)
                .opacity(press ? 0:1)
            Image("fingerprint-2")
                .clipShape(Rectangle().offset(y: tap ? 0:50))
                .scaleEffect(press ? 0:1)
                .opacity(press ? 0:1)
                .animation(.easeInOut, value: tap)
            Image(systemName: "checkmark.circle.fill")
                .font(.system(size: 44,weight: .light))
                .foregroundStyle(background)
                .scaleEffect(press ? 1:0)
                .opacity(press ? 1:0)
                .animation(.easeInOut, value: tap)
        }
        .frame(width: 120,height: 120)
        .background(
            ZStack{
                LinearGradient(gradient: Gradient(colors: [press ? innerColor:whiteColor, press ? whiteColor: innerColor]), startPoint: .topLeading, endPoint: .bottomTrailing)
                Circle()
                    .stroke(Color.clear,lineWidth:10)
                    .shadow(color:shadowColor,radius: press ? 20: 5,x: press ? -5: 5,y:press ? -5: 5)
                Circle()
                    .stroke(Color.clear,lineWidth:10)
                    .shadow(color:whiteColor,radius: 3,x:press ? 3:-3,y:press ? 3:-3)
            }
        )
        .clipShape(Circle())
        .overlay(
            Circle()
                .trim(from: press ? 0.01:1,to:1)
                .stroke(
                    LinearGradient(
                        gradient:
                            Gradient(colors:
                                    [Color(press ? circleColor1:circleColor2),Color(press ? circleColor1:circleColor3)]),
                        startPoint: .topTrailing,
                        endPoint: .bottomLeading
                    ),
                    style: StrokeStyle(lineWidth: 5,lineCap: .round)
                )
                .rotationEffect(Angle(degrees: 90))
                .rotation3DEffect(
                    Angle(degrees: 180),
                                          axis: (x: 1.0, y: 1.0, z: 0.0)
                )
                .animation(.easeInOut, value: tap)
        )
        .shadow(color:press ? whiteColor:shadowColor,radius: 20,x:20,y:20)
        .shadow(color:press ?shadowColor:whiteColor,radius: 20,x:-20,y:-20)
        .scaleEffect(tap ? 1.2:1)
        .animation(.spring(response:0.5,dampingFraction: 0.5), value: tap || press)
        .gesture(
            LongPressGesture()
                .updating($tap, body: { currentState, gestureState, transcation in
                    gestureState = currentState
                })
            
                .onEnded{ value in
                    press.toggle()
                }
        )
    }
}
